package sre2

import (
	"bytes"
	"flag"
	"fmt"
	"os"
	"runtime"
	"strings"
)

var DebugRecord *bool = flag.Bool("debug", true, "show debug record")

func stack() int {
	var i int
	for {
		i++
		_, _, _, ok := runtime.Caller(i)
		if !ok {
			break
		}
	}
	return i
}

func Record(v ...interface{}) {
	if !*DebugRecord {
		return
	}
	pc, file, line, ok := runtime.Caller(1)
	// fmt.Println(string(function(pc)), file, line, ok)
	// _ = pc
	_ = ok
	pos := strings.LastIndex(file, "/")
	if pos != -1 {
		file = string(([]byte(file))[pos+1:])
	}
	fmt.Fprintf(os.Stderr, "%s%s:%d:%s ", strings.Repeat(" ", stack()), file, line, string(function(pc)))
	fmt.Fprintln(os.Stderr, v...)
}

// function returns, if possible, the name of the function containing the PC.
func function(pc uintptr) []byte {
	var (
		dunno     = []byte("???")
		centerDot = []byte("·")
		dot       = []byte(".")
		slash     = []byte("/")
	)

	fn := runtime.FuncForPC(pc)
	if fn == nil {
		return dunno
	}
	name := []byte(fn.Name())
	// The name includes the path name to the package, which is unnecessary
	// since the file name is already included.  Plus, it has center dots.
	// That is, we see
	//	runtime/debug.*T·ptrmethod
	// and want
	//	*T.ptrmethod
	// Since the package path might contains dots (e.g. code.google.com/...),
	// we first remove the path prefix if there is one.
	if lastslash := bytes.LastIndex(name, slash); lastslash >= 0 {
		name = name[lastslash+1:]
	}
	if period := bytes.Index(name, dot); period >= 0 {
		name = name[period+1:]
	}
	name = bytes.Replace(name, centerDot, dot, -1)
	return name
}
